package com.googlecode.particlesys.objects;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;

import com.googlecode.particlesys.Simulation;

public abstract class AbstractEmitter extends Particle {

	private static final Random RANDOM = new Random();
	private final List<Particle> particles = new CopyOnWriteArrayList<Particle>();
	private final int flow;
	private final int radius;
	private final int gravity;
	private int rate;
	private int cycle = 0;
	
	public AbstractEmitter(int width, int height, int x, int y, int flow, int gravity){
		super(randomColor(), width, height);
		super.setX(x);
		super.setY(y);
		this.flow = flow;
		
		Particle p = getNextParticle();
		this.radius = (int) (2*(p.getSpeed()*p.getLife()));
		this.gravity = gravity;
	}
	
	public abstract Particle getNextParticle();
	
	public void step(){}
	
	public void draw(Graphics g, Component component){
		g.setColor(color);
		g.fillRect(x-2, y-2, width, height);
		
		if(Simulation.isDisplayingRadius()){
			g.drawLine(x-2, y-2, x-(radius/2), y-2);
		}
		
		step();
		
		for(Particle p : particles){
			p.update(gravity);
			
			if(p.isExpired()){
				particles.remove(p);
				continue;
			}
			
			p.draw(g, component);
		}
		
		if(particles.size() < flow && (++cycle & rate) == 0){
			particles.add(getNextParticle());
		}
	}

	public List<Particle> getParticles(){
		return particles;
	}
	
	private static Color randomColor(){
		int r = RANDOM.nextBoolean() ? RANDOM.nextInt(255) : RANDOM.nextInt(128);
		int g = RANDOM.nextBoolean() ? RANDOM.nextInt(255) : RANDOM.nextInt(128);
		int b = RANDOM.nextBoolean() ? RANDOM.nextInt(255) : RANDOM.nextInt(128);
		return new Color(r, g, b);
	}

	public void setRate(int rate){
		this.rate = rate;
	}

	public int getRate(){
		return rate;
	}
}